package com.jse.util.concurrent.new1.synchronizer;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * CountDownLatch放到全局是安全的么？倒计时，只要到达阈值就释放
 * @author zenghua233
 *
 */
public class CountDownLatchTest {
	public CountDownLatch globalLatch = new CountDownLatch(1);
	
	@Test
	public void testSimple() throws Exception {
		CountDownLatch latch = new CountDownLatch(1);
		ExecutorService executor = Executors.newCachedThreadPool();
		executor.execute(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(5000);
					System.out.println("this is run task");
					latch.countDown();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		});
		//等待latch变为0
		latch.await();
		System.out.println("test thread");
		
		Thread.currentThread().join();
	}
	
	@Test
	public void testAwait() {
		CountDownLatch latch = new CountDownLatch(1);
		try {
//			latch.countDown();
			latch.await(1000, TimeUnit.MILLISECONDS);
			//会一直等待
//			latch.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 3个线程A,B,C分别按顺序输出A,B,C
	 * 
	 *参考ExcutorTest.testFifoPrint顺序输出
	 */
	@Test
	public void testCountDown() throws Exception {
		ExecutorService executor = Executors.newFixedThreadPool(3);
		for (int i = 0; i <5; i++) {
			executor.execute(new Task("thread-" + i, globalLatch));
			//这里只要一个线程执行了倒计时，后面的限制就没有了，一直通过
			globalLatch.await();
		}

		Thread.sleep(3000);
		System.out.println("====main===");
	}
	
	class Task implements Runnable {
		public String taskName;
		public CountDownLatch latch;
		
		public Task(String taskName, CountDownLatch latch) {
			this.taskName = taskName;
			this.latch = latch;
		}
		
		@Override
		public void run() {
			try {
				Thread.sleep(1000);
				System.out.println(taskName);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				latch.countDown();
			}
		}
	}
}
